package com.embedsky.administrator.mycardemulation;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.widget.EditText;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.embedsky.administrator.mycardemulation.message.MessageAdapter;
import com.embedsky.administrator.mycardemulation.message.SocketMessage;
import com.embedsky.administrator.mycardemulation.p2p.DirectActionListen;
import com.embedsky.administrator.mycardemulation.p2p.P2pManager;
import com.embedsky.administrator.mycardemulation.p2p.ReceiveMessageCallback;
import com.embedsky.administrator.mycardemulation.p2p.WifiP2pBroadcastReceive;
import com.embedsky.administrator.mycardemulation.socket.IServerManager;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@SuppressLint("MissingPermission")
public class MainActivity extends AppCompatActivity implements ReceiveMessageCallback {
    public static Handler dataHandler;
    private String TAG = "MainServer";
    private TextView data;
    private EditText dataedit;
    //public static StringBuilder sb = new StringBuilder();

    private String[] permissionList = {Manifest.permission.ACCESS_FINE_LOCATION};

    private WifiP2pManager wifiP2pManager;
    private WifiP2pManager.Channel channel;
    private boolean connectionInfoAvailable = false;
    private BroadcastReceiver broadcastReceiver;
    private IServerManager serverManager;
    private Handler handler;
    private String clientIp;

    private MainViewModel mainViewModel;

    private MessageAdapter messageAdapter;

    private RecyclerView recyclerView;

    private EditText editText;


    private DirectActionListen directActionListen = new DirectActionListen() {
        @Override
        public void onChannelDisconnected() {
            Log.d(TAG, "onChannelDisconnected: ");
        }

        @Override
        public void wifiP2pEnabled(Boolean enabled) {
            Log.d(TAG, "wifiP2pEnabled: " + enabled);
        }

        @Override
        public void onConnectionInfoAvailable(WifiP2pInfo wifiP2pInfo) {
            Log.d(TAG, "onConnectionInfoAvailable: " + "---isOwner==" + wifiP2pInfo.isGroupOwner + "---isFormed==" + wifiP2pInfo.groupFormed);
            if (wifiP2pInfo.isGroupOwner && wifiP2pInfo.groupFormed) {
                connectionInfoAvailable = true;
            }
            wifiP2pManager.requestPeers(channel, peers -> {
                if (peers.getDeviceList() == null) {
                    Log.d(TAG, "requestPeers fail");
                }
                Log.d(TAG, "onConnectionInfoAvailable: requestPeers");
                for (WifiP2pDevice device : peers.getDeviceList()) {
                    Log.d(TAG, "onPeersAvailable:" + device);
                }
            });
            Log.d(TAG, "onConnectionInfoAvailable: " + wifiP2pInfo);
        }

        @Override
        public void onDisconnection() {
            connectionInfoAvailable = false;
            Log.d(TAG, "onDisconnection: ");

        }

        @Override
        public void onSelfDeviceAvailable(WifiP2pDevice wifiP2pDevice) {
            Log.d(TAG, "onSelfDeviceAvailable: " + wifiP2pDevice);
            getDeviceStatus(wifiP2pDevice);
        }

        @Override
        public void onPeersAvailable(Collection<WifiP2pDevice> wifiP2pDeviceList) {
            for (WifiP2pDevice device : wifiP2pDeviceList) {
                Log.d(TAG, "onPeersAvailable: " + device);
            }

        }

        @Override
        public void onGetDeviceInfo(WifiP2pDevice info) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        requestPermission();
        data = (TextView) findViewById(R.id.data_tv);
        dataedit = (EditText) findViewById(R.id.data_edt);
        dataedit.setText(DataStorage.GetData(this));
        findViewById(R.id.btn_save).setOnClickListener(v -> {
//            String account = dataedit.getText().toString();
//            DataStorage.SetData(MainActivity.this, account);
            //cardService.sendResponseApdu();
            P2pManager.getInstance().discoverPeers(wifiP2pManager, channel);
        });
        handler = new Handler();
        initDevice();
        initView();
        findViewById(R.id.socket).setOnClickListener(v -> {
            //onReceivedReadRequest();
            P2pManager.getInstance().disconnect(wifiP2pManager, channel);
            handler.postDelayed(() -> {
                P2pManager.getInstance().createGroup();
            }, 500);
        });

        findViewById(R.id.disconnect).setOnClickListener(v -> {
            disConnect();
        });

        findViewById(R.id.send_message).setOnClickListener(v -> {
            if (!TextUtils.isEmpty(clientIp)) {
                serverManager.sendData("客户端你好", clientIp);
            }
        });
    }


    private void initViewModel() {
        mainViewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(MainViewModel.class);
        mainViewModel.initSocketServer();
        mainViewModel.messageList.observe(this, (messageList) -> {
            Log.d(TAG, "initViewModel: " + messageList.toString());
            //D/MyCardReader: initViewModel: [SocketMessage{data='hello', type=0}]
            //messageAdapter.notify();
            msgList.add(messageList.get(messageList.size() - 1));
            messageAdapter.notifyItemInserted(messageList.size() - 1);
            recyclerView.scrollToPosition(messageList.size() - 1);
        });
    }

    List<SocketMessage> msgList = new ArrayList<>();

    private void initView() {
        recyclerView = findViewById(R.id.message_list);
        initViewModel();
        messageAdapter = new MessageAdapter(msgList);
        recyclerView.setAdapter(messageAdapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        editText = findViewById(R.id.msgText);
        findViewById(R.id.sendMsg).setOnClickListener(v -> {
            String text = editText.getText().toString();
            editText.setText("");
            if (!TextUtils.isEmpty(text)) {
                mainViewModel.sendData(text);
            }
        });
    }


    private void disConnect() {
        P2pManager.getInstance().disconnect(wifiP2pManager, channel);
        P2pManager.getInstance().removeGroup(wifiP2pManager, channel);
        mainViewModel.stopClient();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        P2pManager.getInstance().disconnect(wifiP2pManager, channel);
    }

    private void initDevice() {
        wifiP2pManager = (WifiP2pManager) getSystemService(WIFI_P2P_SERVICE);
        if (wifiP2pManager == null) {
            finish();
            return;
        }
        channel = wifiP2pManager.initialize(this, getMainLooper(), directActionListen);
        broadcastReceiver = new WifiP2pBroadcastReceive(wifiP2pManager, channel, directActionListen);
        registerReceiver(broadcastReceiver, WifiP2pBroadcastReceive.getIntentFilter());
    }


    private void requestPermission() {
        ActivityCompat.requestPermissions(this, permissionList, 1);
    }


    private void getDeviceStatus(WifiP2pDevice device) {
        int status = device.status;
        switch (status) {
            case WifiP2pDevice.CONNECTED:
                Log.d(TAG, "getDeviceStatus: Connected");
            case WifiP2pDevice.AVAILABLE:
                Log.d(TAG, "getDeviceStatus: AVAILABLE");
            case WifiP2pDevice.FAILED:
                Log.d(TAG, "getDeviceStatus: FAILED");
            case WifiP2pDevice.INVITED:
                Log.d(TAG, "getDeviceStatus: INVITED");
            case WifiP2pDevice.UNAVAILABLE:
                Log.d(TAG, "getDeviceStatus: UNAVAILABLE");
        }
    }

    @Override
    public void onReceivedReadRequest() {
        //P2pManager.getInstance().createGroup(wifiP2pManager, channel);
        //initSocketServer();
    }

}
